﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DimOS.Internals;

namespace DimOS.Constants
{
    public static class Tokens
    {
        public const char WildcardAny = '*';
        public const char WildcardOne = '?';
        public const char Hidden = '.';

        public const char Index = ':';
        public const char Multiply = '*';
        public const char Divide = '/';
        public const char Add = '+';
        public const char Power = '^';
        public const char Remainder = '%';
        public const char Subtract = '-';
        public const char Assignment = '=';
        public const char ValueLeft = '[';
        public const char ValueRight = ']';
        public const char CommandLeft = '{';
        public const char CommandRight = '}';
        public const char ParameterLeft = '(';
        public const char ParameterRight = ')';
        public const char End = ';';
        public const char VerbatimString = '"';
        public const char MirrorLeft = '/';
        public const char MirrorRight = '\\';
        public const char Not = '!';
        public const char Convert = '|';
        public const char Separator = ',';
        public const char Space = ' ';
        public const char NewLine = '\n';
        public const char Empty = '\0';

        public const string Ternary = "::";
        public const string And = "&&";
        public const string Or = "||";
        public const string Xor = "^^";
        public const string Increment = "++";
        public const string Decrement = "--";
        public const string Sort = ">>";
        public const string Reverse = "<<";
        public const string InputRedirect = "=<";
        public const string OutputAppend = "=>";
        public const string OutputRedirect = "=|";
        public const string Equal = "==";
        public const string NotEqual = "!=";
        public const string Less = "<";
        public const string LessOrEqual = "<=";
        public const string More = ">";
        public const string MoreOrEqual = ">=";
        public const string Like = "~~";
        public const string NotLess = "!<";
        public const string NotMore = "!>";
        public const string LessLike = "<~";
        public const string MoreLike = ">~";
        public const string NotLike = "!~";
        public const string In = "><";
        public const string NotIn = "<>";
        public const string AddAssignment = "+=";
        public const string SubtractAssignment = "-=";
        public const string MultiplyAssignment = "*=";
        public const string DivideAssignment = "/=";
        public const string RemainderAssignment = "%=";
        public const string PowerAssignment = "^=";
        public const string IndexAssignment = ":=";
        public const string ConvertAssignment = "|=";

        public const char TerminalShort = '@';
        public const string SubstringShort = "!@";
        public const string ReplaceShort = "@@";

        public const char LoopShort = '#';
        public const string BreakShort = "!#";
        public const string ContinueShort = "##";

        public const char DefineShort = '$';
        public const string ThrowShort = "!$";
        public const string ReturnShort = "$$";

        public const string IfShort = "?";
        public const string TryShort = "!?";
        public const string ElseShort = "??";

        public const string WaitShort = "!!";
        public const char SizeShort = '&';

        public const string Terminal = "io";
        public const string Substring = "substring";
        public const string Replace = "replace";

        public const string Loop = "loop";
        public const string Break = "break";
        public const string Continue = "continue";

        public const string Define = "define";
        public const string Throw = "throw";
        public const string Return = "return";

        public const string If = "if";
        public const string ElseIf = "elif";
        public const string Else = "else";
        public const string Try = "try";

        public const string Type = "type";
        public const string Size = "size";
        public const string Wait = "wait";

        public const string Round = "round";
        public const string Absolute = "abs";
        public const string Ceiling = "ceiling";
        public const string Floor = "floor";

        public const string Pi = "pi";
        public const string SquareRoot = "sqrt";

        public const string Maximum = "max";
        public const string Minimum = "min";

        public const char Dot = '.';
        public const char HereStringLeft = '`';
        public const char HereStringRight = '\'';

        public static string[] Operations =
        {
            Increment, Decrement, Sort, Reverse, InputRedirect, OutputRedirect, OutputAppend, AddAssignment,
            SubtractAssignment, MultiplyAssignment, PowerAssignment, DivideAssignment, RemainderAssignment,
            IndexAssignment, ConvertAssignment, And, Or, Xor, Equal, NotEqual, Like, NotLike, LessOrEqual,
            MoreOrEqual, LessLike, MoreLike, NotLess, NotMore, In, NotIn, Ternary, Index.ToString(), Convert
            .ToString(), Multiply.ToString(), Power.ToString(), Divide.ToString(), Add.ToString(), Subtract
            .ToString(), Remainder.ToString(), Assignment.ToString(), Less, More,
        };

        public static char[] ListStop =
        {
            Space, End, ParameterRight, CommandRight, NewLine,
        };

        public static char[] ListProcess =
        {
            Separator, ParameterRight, CommandRight, End, Space,
        };

        public static char[] Separators =
        {
            Less[0], More[0], Like[0], Assignment, Add, Subtract, Multiply, Divide, Remainder, And[0],
            Or[0], Index, Power, Separator, Not, ParameterLeft, ParameterRight, ValueLeft, ValueRight,
            CommandLeft, CommandRight, '\t', NewLine, End, Space,
        };

        public static List<string> FlowControl = new List<string>
        {
            Break, BreakShort, Continue, ContinueShort, Define, DefineShort.ToString(), If, IfShort,
            Loop, LoopShort.ToString(), Return, ReturnShort, Throw, ThrowShort, Try, TryShort,
        };

        public static List<string> SpaceAllowed = new List<string> { };

        public static List<string> SpaceAllowedOnce = new List<string>
        {
            Define, Return, Throw, Else, Terminal
        };

        public static List<string> SpaceRestore = new List<string>
        {
            DefineShort.ToString(), ReturnShort, ThrowShort, ElseShort, SizeShort.ToString(), TerminalShort.ToString()
        };

        public static List<Token> List = new List<Token>
        {
            //new Token(TokenType.And, "&&", 8),
            //new Token(TokenType.Assignment, Assignment.ToString(), 9),
            //new Token(TokenType.Between, "<>", 8),
            //new Token(TokenType.Equal, "==", 8),
            //new Token(TokenType.In, "><", 8),
            //new Token(TokenType.Less, "<<", 8),
            //new Token(TokenType.LessOrEqual, "<=", 8),
            //new Token(TokenType.Like, "~~", 8),
            //new Token(TokenType.Mirror, MirrorLeft.ToString(), 9),
            //new Token(TokenType.Mirror, MirrorRight.ToString(), 9),
            //new Token(TokenType.More, ">>", 8),
            //new Token(TokenType.MoreOrEqual, ">=", 8),
            //new Token(TokenType.Not, Not.ToString(), 9),
            //new Token(TokenType.NotEqual, "!=", 8),
            //new Token(TokenType.NotLess, "!<", 8),
            //new Token(TokenType.NotLike, "!~", 8),
            //new Token(TokenType.NotMore, "!>", 8),
            //new Token(TokenType.Or, "||", 8),
            //new Token(TokenType.TernaryElse, TernaryElse.ToString(), 9),
            //new Token(TokenType.TernaryIfThen, TernaryIfThen.ToString(), 9),


            //new Token(TokenType.Argument, Argument.ToString(), 9),
            //new Token(TokenType.CommandLeft, CommandLeft.ToString(), 9),
            //new Token(TokenType.CommandRight, CommandRight.ToString(), 9),
            ////new Token(TokenType.CommandLevel, CommandLevel.ToString(), 9),
            //new Token(TokenType.End, End.ToString(), 9),
            ////new Token(TokenType.ParallelExecution, ParallelExecution.ToString(), 9),
            //new Token(TokenType.ParameterLeft, ParameterLeft.ToString(), 9),
            //new Token(TokenType.ParameterRight, ParameterRight.ToString(), 9),
            //new Token(TokenType.Pipe, Convert.ToString(), 9),
            //new Token(TokenType.Separator, Separator.ToString(), 9),
            //new Token(TokenType.Space, Space.ToString(), 9),
            //new Token(TokenType.ValueLeft, ValueLeft.ToString(), 9),
            //new Token(TokenType.ValueRight, ValueRight.ToString(), 9),

            new Token(TokenType.Path, "", 2, true),
            new Token(TokenType.Function, "", 2, true),
            //new Token(TokenType.Path, "", 2, true),
            //new Token(TokenType.Command, "", 2, true),
            //new Token(TokenType.DateTime, "", 1, true),
            //new Token(TokenType.Number, "", 1, true),
            //new Token(TokenType.HereString, "", 0, true),
            new Token(TokenType.VerbatimString, "", 1, true),
        };
    }
}
